package ldk.util.refresh;

import android.animation.ValueAnimator;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.util.Log;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import static ldk.util.refresh.RefreshLayout.ORIENTATION_BOTTOM;
import static ldk.util.refresh.RefreshLayout.ORIENTATION_LEFT;
import static ldk.util.refresh.RefreshLayout.ORIENTATION_RIGHT;
import static ldk.util.refresh.RefreshLayout.ORIENTATION_TOP;

public class SimpleRefreshManager extends RefreshLayout.RefreshManager {
    private static final String TAG = "SimpleRefreshManager";

    @Override
    public boolean onFinish(float tmpDownValue, float lastDownAxisValue) {
        super.onFinish(tmpDownValue, lastDownAxisValue);
        final float overScrollDelta = (tmpDownValue - lastDownAxisValue) * 0.5f;
        finishRefresh(overScrollDelta);
        return true;
    }

    @Override
    public boolean onMove(float downValue, float lastDownAxisValue) {
        final float deltaValue = (downValue - lastDownAxisValue) * 0.5f;
        return showHeaderViewDelta(deltaValue);
    }

    @Override
    public void setHeaderViewListener(@Nullable HeaderViewListener listener) {
        super.setHeaderViewListener(listener);
        if (listener instanceof SimpleRefreshListener){
            ((SimpleRefreshListener) listener).mSimpleRefreshManager = this;
        }
    }

    private void finishRefresh(float overscrollDelta) {
        Log.d(TAG, "finishRefresh");
        if (!showHeaderViewDelta(overscrollDelta)){
            return;
        }
        View mTarget = getTargetView();
        View mHeaderView = getHeaderView();
        float currentTranslationX = ViewCompat.getTranslationX(mTarget);
        float currentTranslationY = ViewCompat.getTranslationY(mTarget);
        if (mHeaderView != null){
            boolean isEnough = false;
            switch (getOrientation()){
                case ORIENTATION_RIGHT:
                    isEnough = currentTranslationX < -mHeaderView.getMeasuredWidth() / 2;
                    break;
                case ORIENTATION_LEFT:
                    isEnough = currentTranslationX > mHeaderView.getMeasuredWidth() / 2;
                    break;
                case ORIENTATION_TOP:
                    isEnough = currentTranslationY > mHeaderView.getMeasuredHeight() / 2;
                    break;
                case ORIENTATION_BOTTOM:
                    isEnough = currentTranslationY < -mHeaderView.getMeasuredHeight() / 2;
                    break;
            }
            if (isEnough){
                animateToRefreshing();
            }else{
                animateToOriginal();
            }
        }else{
            animateToOriginal();
        }
    }

    @Override
    public void setRefresh(boolean isRefreshing) {
        if (!isRefreshing) animateToOriginal();
        else animateToRefreshing();
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        if (isHorizontal()){
            switch (getOrientation()){
                case RefreshLayout.ORIENTATION_LEFT:
                    break;
                case RefreshLayout.ORIENTATION_RIGHT:
                    float translationX = ViewCompat.getTranslationX(getTargetView());
                    if (direction < 0){
                        return translationX < 0;
                    }else{
                        return translationX >= -196;
                    }
            }
        }
        return false;
    }

    @Override
    public boolean canScrollVertically(int direction) {
        if (isHorizontal()) return false;
        switch (getOrientation()){
            case RefreshLayout.ORIENTATION_TOP:
                break;
            case RefreshLayout.ORIENTATION_BOTTOM:
                break;
        }
        return false;
    }

    private boolean showHeaderViewDelta(float deltaValue) {
        float currentTranslationValue = isHorizontal() ? ViewCompat.getTranslationX(getTargetView())
                : ViewCompat.getTranslationY(getTargetView());
        float translationValue = currentTranslationValue + deltaValue;
        switch (getOrientation()){
            case RefreshLayout.ORIENTATION_RIGHT:
            case RefreshLayout.ORIENTATION_BOTTOM:
                if (translationValue >= 0) return false;
                break;
            case RefreshLayout.ORIENTATION_LEFT:
            case RefreshLayout.ORIENTATION_TOP:
                if (translationValue <= 0) return false;
        }
        float translationValueAbs = Math.abs(translationValue);
        if (translationValueAbs > 200 && translationValueAbs > Math.abs(currentTranslationValue)){
            Log.d(TAG, "showHeaderView, 并且高度够了");
            return false;
        }else{
            showHeaderView(translationValue);
            return true;
        }
    }

    public void animateToRefreshing() {
        float currentTranslationValue = isHorizontal() ? ViewCompat.getTranslationX(getTargetView())
                : ViewCompat.getTranslationY(getTargetView());
        float endValue = 0;
        View mHeaderView = getHeaderView();
        switch (getOrientation()){
            case ORIENTATION_RIGHT:
                endValue = -mHeaderView.getMeasuredWidth();
                break;
            case ORIENTATION_LEFT:
                endValue = mHeaderView.getMeasuredWidth();
                break;
            case ORIENTATION_TOP:
                endValue = mHeaderView.getMeasuredHeight();
                break;
            case ORIENTATION_BOTTOM:
                endValue = -mHeaderView.getMeasuredHeight();
                break;
        }
        ValueAnimator animator = ValueAnimator.ofFloat(currentTranslationValue, endValue).setDuration(100);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                showHeaderView((Float) animation.getAnimatedValue());
            }
        });
        animator.start();
    }

    public void animateToOriginal(){
        View mTarget = getTargetView();
        float currentTranslationValue = isHorizontal() ? ViewCompat.getTranslationX(mTarget) : ViewCompat.getTranslationY(mTarget);
        ValueAnimator animator = ValueAnimator.ofFloat(currentTranslationValue, 0).setDuration(100);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                showHeaderView((float)animation.getAnimatedValue());
            }
        });
        animator.start();
    }
}